<?php
/**
 * rsa class
 * User: functions
 * Date: 2016/1/28
 * Time: 12:43
 */

namespace Tools\Rsa;

class Rsa
{
    //私钥
    private $privateKey;
    //公钥
    private $publicKey;
    //密钥路径
    private $keyPath;
    //加密因子
    private $encrypted = '';
    //解密因子
    private $decrypted = '';
    //密钥长度
    private $rsaBit = 1024;
    //私钥和公钥文件名称
    private $piKeyName = 'private.key';
    private $puKeyName = 'public.key';

    public function __construct($keyPath = '')
    {
        if(!empty($keyPath) && is_dir($keyPath)) {
            $this->keyPath = $keyPath;
        } else {
            throw new \InvalidArgumentException("Invalid Rsa Key Path");
        }

        $this->getPuKey();
        $this->getPiKey();
    }

    /**
     * 获取公钥
     */
    protected function getPuKey()
    {
        $puKeyPath = $this->keyPath . DIRECTORY_SEPARATOR . $this->puKeyName;
        if(file_exists($puKeyPath)) {
            $publicKey = file_get_contents($puKeyPath);
            $this->publicKey = openssl_pkey_get_public($publicKey);
        }
    }

    /**
     *  获取私钥
     */
    protected function getPiKey()
    {
        $piKeyPath = $this->keyPath . DIRECTORY_SEPARATOR . $this->piKeyName;
        if(file_exists($piKeyPath)) {
            $privateKey = file_get_contents($piKeyPath);
            $this->privateKey = openssl_pkey_get_private($privateKey);
        }
    }

    //私钥加密
    public function piEncrypt($data)
    {
        openssl_private_encrypt($data, $this->encrypted, $this->privateKey);//私钥加密
        return base64_encode($this->encrypted);
    }

    //公钥解密
    public function puDecrypt($data)
    {
        $encrypted = base64_decode($data);
        openssl_public_decrypt($encrypted, $this->decrypted, $this->publicKey);//公钥解密
        return $this->decrypted;
    }

    //公钥加密
    public function puEncrypt($data)
    {
        openssl_public_encrypt($data, $this->encrypted, $this->publicKey);//公钥加密
        return $this->encrypted;
    }

    //私钥解密
    public function piDecrypt($data)
    {
        $encrypted = $data;
        openssl_private_decrypt($encrypted, $this->decrypted, $this->privateKey);//私钥解密
        return $this->decrypted;
    }

    /**
     * 加密
     * @param $data
     * @return string
     */
    public function rsaEncrypt($data)
    {
        $inputLen = strlen($data);
        $offSet = 0;
        $i = 0;
        $maxDecryptBlock = $this->rsaBit / 8 - 11;

        $en = '';
        // 对数据分段加密
        while($inputLen - $offSet > 0) {

            if($inputLen - $offSet > $maxDecryptBlock) {
                $cache = $this->puEncrypt(substr($data, $offSet, $maxDecryptBlock));
            } else {
                $cache = $this->puEncrypt(substr($data, $offSet, $inputLen - $offSet));
            }
            $en = $en . $cache;

            $i++;
            $offSet = $i * $maxDecryptBlock;
        }

        return base64_encode($en);
    }

    /**
     * 解密 ，超过1024
     * @param $data
     * @return string
     */
    public function rsaDecrypt($data)
    {
        $data = base64_decode($data);
        $inputLen = strlen($data);
        $offSet = 0;
        $i = 0;

        $maxDecryptBlock = $this->rsaBit / 8;
        $de = '';
        // 对数据分段解密
        while($inputLen - $offSet > 0) {
            if($inputLen - $offSet > $maxDecryptBlock) {
                $cache = $this->piDecrypt(substr($data, $offSet, $maxDecryptBlock));
            } else {
                $cache = $this->piDecrypt(substr($data, $offSet, $inputLen - $offSet));
            }

            $de = $de . $cache;

            $i = $i + 1;
            $offSet = $i * $maxDecryptBlock;
        }
        return $de;
    }

}